﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DC2010.Objects.Base;
using DC2010.Objects.Structures;
using System.Xml.Serialization;

namespace DC2010
{
    public class ATTACKPARAMETERS
    {
        /// <summary>
        /// Attacker. Root.I.CreatureSystem.GetData(pParam.charIdx);
        /// </summary>
        public int charIdx;                           //pre-attack
        public ActionInfo attackType;                        //pre-attack
      public int    attackX;                           //pre-attack
      public int    attackY;                           //pre-attack

        /// <summary>
        /// Monster under attack. Root.I.CreatureSystem.GetData(pParam.monsterUnderAttack);
        /// </summary>
        public string monsterUnderAttack; //0 if none    //pre-attack
      int    monsterType;                       //pre-attack
      public int    skillNumber;                       //pre-attack
      public int    staminaCost;                       //pre-attack
      public int    experienceGained;                  //pre-attack
      public int    disableTime;                       //pre-attack
      public int    neededMana;                        //pre-attack
      int    unused; //damageToMonster;
      int    decrementCharges;
      public int    activateMonster;
//      int    userInfo[10];
      public ATTACKDATATYPE dataType; // = ADT_*****
        public ATTDEP attdep;
      //ATTACKPARAMETERS(void){memset(this, 0, sizeof(*this));};

        public ATTACKPARAMETERS()
        {
            dataType = new ATTACKDATATYPE();
            attdep = new ATTDEP();
        }
    };

    public class ATTDEP
    {
        public WARCRYETC warcryetc;//      warcryetc;
        public PHYSICALATTACK physicalAttack;// physicalAttack;
        public SPELLATTACK spellAttack;//    spellAttack;
        public HITDOOR hitDoor;//        hitDoor;
        public SHOOT shoot;//          shoot;
        public FLIP flip;//           flip;
        public SHIELD shield;//         shield;
        public HEAL heal;//           heal;
        public FREEZELIFE freezeLife;//     freezeLife;
        public LIGHT light;//          light;
        public THROW thro;//         thro;  // Cannot say 'throw'; it is reserved!

        public ATTDEP()
        {
            warcryetc = new WARCRYETC();
            physicalAttack = new PHYSICALATTACK();
            spellAttack = new SPELLATTACK();
            hitDoor = new HITDOOR();
            shoot = new SHOOT();
            flip = new FLIP();
            shield = new SHIELD();
            heal = new HEAL();
            freezeLife = new FREEZELIFE();
            light = new LIGHT();
            thro = new THROW();
        }
    };

    public enum MONSTER_DAMAGE_RESULT
    {
        NO_MONSTER_DIED = 0,
        SOME_NOT_ALL_MONSTERS_DIED = 1,
        ALL_MONSTERS_DIED = 2
    };

    public enum ATTACKDATATYPE
    {
        ADT_WarCry = 1,
        ADT_Physical = 2,
        ADT_Spell = 3,
        ADT_HitDoor = 4,
        ADT_Shoot = 5,
        ADT_Flip = 6,
        ADT_Shield = 7,
        ADT_FluxCage = 8,
        ADT_Fusion = 9,
        ADT_Heal = 10,
        ADT_Window = 11,
        ADT_ClimbDown = 12,
        ADT_FreezeLife = 13,
        ADT_Light = 14,
        ADT_Throw = 15,
        ADT_Default = 16  //Block, Hit
    };


    public class LOCATIONREL
    {
        public int l;
        public int x;
        public int y;
        public int p;
    };

    public class FILTER
    {
        public LOCATIONREL locrFilter;
        //TIMER timer;
        int DSAobj;

        public FILTER()
        {
            locrFilter = new LOCATIONREL();
        }
    };

    public class WARCRYETC //dataType = ADT_WarCry
    // atk_CONFUSE:
    // atk_WARCRY:
    // atk_CALM:
    // atk_BRANDISH:
    // atk_BLOWHORN:
    {
        public int mastery;
        public int skillIncrement;
        public int effectiveMastery;
        public int requiredMastery;
    };


    public class PHYSICALATTACK //dataType = ADT_Physical
    {
    //  atk_BASH:
    //  atk_HACK:
    //  atk_BERZERK:
    //  atk_KICK:
    //  atk_SWING:
    //  atk_CHOP:
    //  atk_DISRUPT:
    //  atk_JAB:
    //  atk_PARRY:
    //  atk_STAB2:
    //  atk_STAB1:
    //  atk_STUN:
    //  atk_THRUST:
    //  atk_MELEE:
    //  atk_SLASH:
    //  atk_CLEAVE:
    //  atk_PUNCH:
        public int monsterDamage;
        public int staminaAdjust;
        public int skillAdjust;
        public int attackedMonsterOrdinal;
    };

    public class SPELLATTACK //dataType = ADT_Spell
    {
    //  atk_LIGHTNING:
    //  atk_DISPELL:
    //  atk_FIREBALL:
    //  atk_SPIT:
    //  atk_INVOKE
        public int spellRange;
        public string spellType;
        public int decrementCharges; // if non-zero (default = 1)
    };

    public class HEAL
    {
    //  atk_HEAL
        public int HPIncrement;
    };

    public class FREEZELIFE
    {
        public int oldTime;
        public int deltaTime;
    };

    public class LIGHT
    {
        public int deltaLight;
        public int decayRate;
        public int time;
    };

    public class THROW
    {
        public int side;
        public int abort;
        public Directions facing;
        public int range;
        public int damage;
        public int decayRate;
    };

    public class SHIELD // dataType = ADT_Shield
    {
    // atk_SPELLSHIELD
    // atk_FIRESHIELD
        public int mustHaveMana;
        public int strength;
    };

    public class FLIP // dataType = ADT_Flip
    {
    // atk_FLIP
      public int heads;
    };

    public class SHOOT //dataType = ADT_Shoot
    {
    // atk_SHOOT
        public int success;
        public int range;
        public int damage;
        public int decayRate;
    };


    public class HITDOOR //dataType = ADT_HitDoor
    {
    //  atk_BASH:
    //  atk_HACK: 
    //  atk_BERZERK: 
    //  atk_KICK: 
    //  atk_SWING: 
    //  atk_CHOP: 
        public int strength;
    };

    public enum ADJUSTSKILLSWHY
    {
      ASW_Unknown                 = 0,
      ASW_PhysicalAttack          = 1,
      ASW_WarCryEtc               = 2,
      ASW_Attack                  = 3,
      ASW_CastSpell1              = 4,
      ASW_CastSpell2              = 5,
      ASW_MonsterDamagesCharacter = 6,
      ASW_SkillIncreaser1         = 7,
      ASW_SkillIncreaser2         = 8,
      ASW_ThrowByCharacter        = 9,
    };

    public enum DELETEMONSTERWHY
    {
      DMW_Unknown                 = 0,
      DMW_Fusion                  = 1,
      DMW_MakeRoom                = 2,
      DMW_Damage                  = 3,
      DMW_Movement1               = 4,
      DMW_Movement2               = 5,
      DMW_numWhy                  = 6,
    };


    [Flags]
    public enum CHARFLAGS
    {
        CHARFLAG_nonGraphicFlags = 0x007f,
        CHARFLAG_attackDisable = 0x0008,
        CHARFLAG_male = 0x0010,
        CHARFLAG_cursor = 0x0080,
        CHARFLAG_statsChanged = 0x0100,  // Mana, hp, stamina, food, water, poison, etc
        CHARFLAG_possession = 0x0200,
        //  CHARFLAG_0280             = 0x0280,
        //  CHARFLAG_0300             = 0x0300,
        CHARFLAG_positionChanged = 0x0400,
        //  CHARFLAG_0680             = 0x0680,
        CHARFLAG_chestOrScroll = 0x0800,
        //  CHARFLAG_0900             = 0x0900,
        CHARFLAG_portraitChanged = 0x1000, // Born, died, shield change, etc
        CHARFLAG_ouches = 0x2000,
        //  CHARFLAG_2200             = 0x2200,
        CHARFLAG_viewportChanged = 0x4000,
        //  CHARFLAG_5b80             = 0x5b80,
        CHARFLAG_weaponAttack = 0x8000, // Change in weapon or attack status
        //  CHARFLAG_8008             = 0x8008,
        //  CHARFLAG_9400             = 0x9400,
        CHARFLAG_a180 = 0xa180,
        CHARFLAG_graphicFlags = 0xff80,
    };

    public enum EXPOOL_DATA_TYPE
    {
        EDT_MessageParameters = 1,
        EDT_ExtendedCellFlags = 2, //one 32-bit word per flag
        ECF_FOOTPRINTS = 0,
        EDT_SpecialLocations = 3,
        ESL_MONSTERATTACKFILTER = 0,
        ESL_FEEDINGFILTER = 1,
        ESL_MONSTERMOVEFILTER = 2,
        ESL_VIEWINGFILTER = 3,
        ESL_PARTYATTACKFILTER = 4,
        ESL_INDIRECTACTIONS = 5,
        ESL_ADJUSTSKILLSFILTER = 6,
        ESL_DELETEMONSTERFILTER = 7,
        ESL_SOUNDFILTER = 8,
        ESL_CURSORFILTER = 9,
        ESL_ACTIONNAMEFILTER = 10,
        ESL_CHARDEATHFILTER = 11,
        ESL_EQUIPFILTER = 12,
        ESL_MISSILEENCOUNTERFILTER = 13,
        ESL_PARTYMOVEFILTER = 14,
        ESL_DAMAGECHARFILTER = 15,
        EDT_Skins = 4,
        EDT_Database = 5,
        EDBT_ObjectWeights = 0,
        EDBT_DeleteDuplicateTimers = 1,
        EDBT_RuntimeFileSignatures = 2,
        EDBT_Debuging = 3,
        EDBT_GlobalVariables = 4,
        EDBT_DisableSaves = 5,
        EDBT_MonsterNames = 6,
        EDBT_DSAtraces = 7,
        EDBT_AltMonGraphics = 8,
        EDT_Statistics = 6,
        ESTAT_NumMonsterKilled = 0, // A record for each monster type (four sub-types)
        EDT_Palette = 7,
        // 16-word (64 byte) records.  Subtype = 0 to 11.  0-3 = red; 4-7 = green; 8-11 = blue

        // A character removed from the party and waiting in the wings.  Eight 25-word records.
        EDT_Character = 8,           // Keybits 24-31
        // Record number (0-7) in bits 16-23.
        // Fingerprint in bits 0-15.
        EDT_ChampionBones = 9,           // Key = bonesObject.ConvertToOnteger()
        // Contents is fingerprint of dead champion.
        EDT_GlobalText = 10,          // Key = 16-bit integer
    };

    public class SKILL // 6-byte structure in character
    {
        [XmlAttribute]
        public int tempAdjust;  // Temporary adjustment to experience.

        [XmlAttribute]
        public int experience;  // Experience in this skill

        public override string ToString()
        {
            return string.Format("{0} (+{1})", experience, tempAdjust);
        }
    };

    public enum SkillNames
    {
        SKILL_Fighter = 0,
        SKILL_Ninja = 1,
        SKILL_Priest = 2,
        SKILL_Wizard = 3,
        SKILL_Swing = 4,
        SKILL_Thrust = 5,
        SKILL_Club = 6,
        SKILL_Parry = 7,
        SKILL_Steal = 8,
        SKILL_Fight = 9,
        SKILL_Throw = 10,
        SKILL_Shoot = 11,
        SKILL_Identify = 12,
        SKILL_Heal = 13,
        SKILL_Influence = 14,
        SKILL_Defend = 15,
        SKILL_Fire = 16,
        SKILL_Air = 17,
        SKILL_Earth = 18,
        SKILL_Water = 19
    };

        public class DELETEMONSTERPARAMETERS
        {
            public DELETEMONSTERPARAMETERS(DELETEMONSTERWHY w, int idx)
            {
                why = w;
                index = idx;
            }

            public int monsterID;
            public int level;
            public int x;
            public int y;
          DELETEMONSTERWHY why;
          public int dropResidue; // The pre-defined items like Worm Rounds or Screamer Slices
                                        // 0=default; 1=drop; 2=noDrop;
          public int deathCloud;  //0=default; 1=show cloud; 2=Do not show cloud;
          public int index;       // index in group (-1=entire group).
          //

        };


        public enum STATE_OF_FEAR
        {
            StateOfFear0 = 0,
            StateOfFear2 = 2,
            StateOfFear3 = 3,
            StateOfFear4 = 4,
            StateOfFear5 = 5,
            StateOfFear6 = 6,
            StateOfFear7 = 7,
        };

        public enum ATTACKTYPE
        {
            atk_JUGGLE = 0, //Not in CSB
            atk_BLOCK = 1,
            atk_CHOP = 2,
            atk_SPEED = 3, //Not in CSB
            atk_BLOWHORN = 4,
            atk_FLIP = 5,
            atk_PUNCH = 6,
            atk_KICK = 7,
            atk_WARCRY = 8,
            atk_STAB1 = 9,
            atk_CLIMBDOWN = 10,
            atk_FREEZELIFE = 11,
            atk_HIT = 12,
            atk_SWING = 13,
            atk_STAB2 = 14,
            atk_THRUST = 15,
            atk_JAB = 16,
            atk_PARRY = 17,
            atk_HACK = 18,
            atk_BERZERK = 19,
            atk_FIREBALL = 20,
            atk_DISPELL = 21,
            atk_CONFUSE = 22,
            atk_LIGHTNING = 23,
            atk_DISRUPT = 24,
            atk_MELEE = 25,
            atk_PRAY = 26, // Not in CSB
            atk_INVOKE = 27,
            atk_SLASH = 28,
            atk_CLEAVE = 29,
            atk_BASH = 30,
            atk_STUN = 31,
            atk_SHOOT = 32,
            atk_SPELLSHIELD = 33,
            atk_FIRESHIELD = 34,
            atk_FLUXCAGE = 35,
            atk_HEAL = 36,
            atk_CALM = 37,
            atk_LIGHT = 38,
            atk_WINDOW = 39,
            atk_SPIT = 40,
            atk_BRANDISH = 41,
            atk_THROW = 42,
            atk_FUSE = 43
        };

        public enum ERRORCODES
        {
            SER_OK = 0,
            SER_UnknownLocType = 1,
            SER_NoObjInCursor = 2,
            SER_IllegalCharacterIndex = 3,
            SER_IllegalCarryLocation = 4,
            SER_NoObjectAtCarryLocation = 5,
            SER_InvalidCellLocation = 6,
            SER_NoSuchObjectInCell = 7,
            SER_IllegalMonsterID = 8,
            SER_MonsterIsNotMonster = 9,
            SER_NoSuchObjectOnMonster = 10,
            SER_IllegalChestID = 11,
            SER_ChestIsNotChest = 12,
            SER_NoSuchObjectInChest = 13,
            SER_ChestBelongsToCharacter = 14,
            SER_NoCloudsPlease = 15,
            SER_BadCloudTimer = 16,
            DER_OK = 0,
            DER_UnknownLocType = -1,
            DER_IllegalCharacterIndex = -2,
            DER_IllegalPossessionIndex = -3,
            DER_PossessionSlotNotEmpty = -4,
            DER_IllegalObjectForCarryLocation = -5,
            DER_CursorNotEmpty = -6,
            DER_InvalidCellLocation = -7,
            DER_IllegalDepth = -8,
            DER_IllegalChestID = -9,
            DER_ChestIsNotAChest = -10,
            DER_ChestBelongsToCharacter = -11,
            DER_ChestIsFull = -12,
            DER_IllegalMonsterID = -13,
            DER_MonsterIsNotAMonster = -14,
            DER_NoCloudsPlease = -15,
        };


        public class CHARACTER_SEARCH_PACKET
        {
            BaseObject objectToLookFor;
            bool found;
            int characterIndex;
            int locationOnCharacter; //-1 means cursor
            BaseObject RNchest;  // if found as direct content of a chest
            BaseObject RNprevObject; // if not first in a list;
        };

        public class CURSORFILTER_PACKET
        {
          public BaseObject                bo; // = RNnul
          public CURSORFILTER_TYPE type;   // = CURSORFILTER_Unknown
          public int                p1;     // = 0
          public int                p2;     // = 0
          public int                p3;     // = 0
          public int                p4;     // = 0
        };

        public enum CURSORFILTER_TYPE
        {
            CURSORFILTER_Unknown = 0,

            CURSORFILTER_ReadGame = 1,   // P1 = P2 = P3 = P4 = 0

            CURSORFILTER_PickFromFloor = 2,   // Can be Canceled.  The effect will
            // be as if a Screamer were sitting
            // on top of the object.
            // P1 = level
            // P2 = relative x
            // P3 = relative y
            // P4 = position

            CURSORFILTER_PlaceOnCharacter = 3,   // 'PlaceOnCharacter' and 'PickFromCharacter'
            // are connected because it is possible to
            // swap the contents of the cursor with the
            // object in the character's possession.
            // In order to allow the filter to cancel the
            // entire operation, the filter is always called
            // with type 'CURSORFILTER_PlaceOnCharacter'
            // even if the cursor is totally empty.  In such
            // a case, the object is RNnul (0xffff).
            // The operation can be canceled by setting
            // the type to CURSORFILTER_Cancel.  The effect
            // will be as if the object in the cursor cannot
            // be placed in the particular possession slot.
            // As if you tried to place a chest on the 
            // character's head.
            // P1 = Character Index
            // P2 = Position on character

            CURSORFILTER_PickFromCharacter = 4,   // This always follows the 'PlaceOnCharacter'
            // operation unless the operation has been
            // canceled or there is not object in the
            // particular possession slot.
            // See discussion at 'PlaceOnCharacter'.
            // P1 = Character Index
            // P2 = Position on character

            CURSORFILTER_Throw = 5,   // Can be canceled.  The object will
            // remain in the hand.
            // P1 = Left or Right

            CURSORFILTER_EnteringPrison = 6,   // P1 = P2 = P3 = P4 = 0

            CURSORFILTER_DropObject = 7,   // Can be canceled.  The object will
            // remain in the hand.
            // P1 = level
            // P2 = relative x
            // P3 = relative y
            // P4 = position

            CURSORFILTER_Eat = 8,   // Gulp

            CURSORFILTER_ResumeSavedGame = 9,

            CURSORFILTER_DSA_DEL = 10,

            CURSORFILTER_DSA_ADD = 11,

            CURSORFILTER_TakeFromTorchHolder = 12,  // Can be canceled.  The same effect
            // as if no object of the correct type
            // was available at the holder's location.
            // P1 = level
            // P2 = relative x
            // P3 = relative y
            // P4 = position

            CURSORFILTER_PlaceInTorchHolder = 13,  // Can be canceled.  It would act as
            // if the torch holder already contained
            // a torch.
            // P1 = level
            // P2 = relative x
            // P3 = relative y
            // P4 = position

            CURSORFILTER_SwapRemove = 14,  // 'SwapRemove' and 'SwapReplace'
            // are connected because they act together to
            // swap the contents of the cursor with the
            // object at the actuator's location..
            // In order to allow the filter to cancel the
            // entire operation, the filter is always called
            // with type 'CURSORFILTER_SwapRemove' first.
            // The operation can be canceled by setting
            // the type to CURSORFILTER_Cancel.  The effect
            // will be as if there is no object
            // at the actuator's location.
            // P1 = level        //Actuator type 16
            // P2 = relative x
            // P3 = relative y
            // P4 = position

            CURSORFILTER_SwapReplace = 15,  // See discussion of 'SwapRemove'.
            // P1 = level        //Actuator type 16
            // P2 = relative x
            // P3 = relative y
            // P4 = position

            CURSORFILTER_GiftFromGod = 16,  // Can be canceled.
            // P1 = level        //Actuator type 12
            // P2 = relative x
            // P3 = relative y
            // P4 = position

            CURSORFILTER_TakeKey = 17,  // Can be canceled.  Everything will work
            // exactly as before but the key will
            // remain in the player's hand.
            // P1 = level
            // P2 = relative x
            // P3 = relative y
            // P4 = position

            CURSORFILTER_DSA_MoveFrom = 18,

            CURSORFILTER_DSA_MoveTo = 19,

            CURSORFILTER_Cancel = 20,  // Some cursor actions can be canceled
            // by setting the type to this value.

        };












}
